#include "dithering.h"

QImage RandomDithering(QImage &image)
{
    int width = image.width();
    int height = image.height();
    QImage ret = image.copy();

    for(int i = 0; i < height; i ++)
    {
        uchar * p = ret.scanLine(i);
        for(int j = 0; j < width; j ++)
        {
            int x = rand() % 256;
            p[j] = ( x <= p[j] ?  255 : 0 );
        }
    }
    return ret;
}
QImage RandomDithering(QImage &image, int dither)
{
    int width = image.width();
    int height = image.height();
    QImage ret = image.copy();

    for(int i = 0; i < height; i ++)
    {
        uchar * p = ret.scanLine(i);
        for(int j = 0; j < width; j ++)
        {
            int x = rand() % (2 * dither) - dither;
            p[j] = (p[j] + x >= 128 ? 255 : 0);
        }
    }
    return ret;
}
QImage FloydSteinbergDithering(QImage &image)
{
    int width = image.width();
    int height = image.height();
    QImage ret = image.copy();
    for(int i = 0; i < height - 1; i ++)
    {
        uchar * p = ret.scanLine(i);
        uchar *pNext = ret.scanLine(i + 1);
        for(int j = 0; j < width - 1; j ++)
        {
            int diff;
            if( p[j] > 128 )
            {
                diff = p[j] - 255;
                p[j] = 255;
            }
            else
            {
                diff = p[j];
                p[j] = 0;
            }
            pNext[j] = qBound(0, pNext[j] + diff * 3 / 16, 255);
            p[j + 1] = qBound(0, p[j + 1] + diff * 3 / 16, 255);
            pNext[j + 1] = qBound(0, pNext[j + 1] + diff * 1 / 4, 255);
        }
        p[width - 1] = (p[width - 1] >= 128 ? 255 : 0);
    }
    uchar * p = ret.scanLine(height - 1);
    for(int j = 0; j < width; j ++)
    {
        p[j] = (p[j] >= 128 ? 255 : 0);
    }
    return ret;
}
